今天要用滑鼠在網頁上畫畫。
初探Canvas元素的使用方式,可與MDN的Canvas教學手冊搭配服用
但若是只想知道此實例用到的指令,程式碼中會有簡易的註解,幫助理解。
首先先抓出畫布的位置,
再利用 getContext() 獲取 Canvas 繪圖物件,
傳入參數 '2d' 得到 CanvasRenderingContext2D 物件
作為 Canvas 2D 的渲染環境。
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
再來要做一些基礎設定
canvas.width = window.innerWidth; // 設定畫布的寬度
canvas.height = window.innerHeight;// 設定畫布的高度
ctx.strokeStyle = "#BADA55"; // 設定勾勒圖形時用的顏色
ctx.lineJoin = "round"; // 指定兩條線連結處的屬性,這裡選擇用圓角
ctx.lineCap = "round"; // 指定每一條線末端的屬性,這裡選擇用圓角
設置待會會使用到的變數
let isDrawing = false; // 用來判斷是否正在畫圖
let lastX = 0; //用來設定畫筆的X座標
let lastY = 0; //用來設定畫筆的Y座標
今日目標:用滑鼠畫畫,想必監聽器就是要抓取滑鼠的動態拉
設置監聽器:
canvas.addEventListener("mousemove", draw);
一個簡單的函式,看看目前可以抓到的event
function draw(e) {
console.log(e);
}
現在只要滑鼠有移動,皆會印出event,
但我們需要的是滑鼠按下時才是確定要畫圖的時候。
滑鼠按下 => 畫圖中
滑鼠放開 => 不畫圖
滑鼠移出畫布 => 不畫圖
因此,監聽器需要依據這些條件增加
canvas.addEventListener("mousemove", draw);
canvas.addEventListener("mousedown", () => (isDrawing = true));
canvas.addEventListener("mouseup", () => (isDrawing = false));
canvas.addEventListener("mouseout", () => (isDrawing = false));
函式就可以這麼寫
function draw(e) {
if (!isDrawing) return; //如果不是在mousedown的時候,這個function不作用
console.log(e);
}
draw這個函式就只會在mousedown的條件下才會執行。
大家都知道點線面,兩點才能連成一條線,
所以我們需要線的起始位置跟線的結束位置,在Canvas中,
都會使用(x,y)座標表示。知道這個原理,就可以進行下一步的撰寫
function draw(e) {
if (!isDrawing) return; //如果不是在mousedown的時候,這個function不作用
console.log(e);
ctx.beginPath() //產生一個新路徑,產生後再使用繪圖指令來設定路徑
ctx.moveTo(lastX, lastY) //moveTo()不會畫任何圖形,但卻是上述路徑清單的一部分,這大概有點像是把筆從紙上一點提起來,然後放到另一個點。
ctx.lineTo(e.offsetX, e.offsetY)//從目前繪圖點畫一條直線到指定的(x, y)座標點。
ctx.stroke()//stroke() 會繪製出通過 moveTo() 和 lineTo() 方法定義的路径。默認颜色是黑色。
}
以為大功告成了,
結果發現給予moveTo()的座標,一直都是(0,0),
我們需要在畫線結束的時候,更新moveTo()的座標
function draw(e) {
...
ctx.stroke(); //stroke() 會繪製出通過 moveTo() 和 lineTo() 方法定義的路径。默認颜色是黑色。
lastX = e.offsetX; //
lastY = e.offsetY; //
}
但是這樣最一剛開始的起點還是(0,0),
並不是我們滑鼠隨機按下的第一個座標點,
因此在滑鼠按下的時候需要更新moveTo()的座標點
監聽器就改寫成
canvas.addEventListener("mousedown", (e) => {
console.log(e);
isDrawing = true;
lastX = e.offsetX;
lastY = e.offsetY;
});
到這裡,基礎的功能都已經完成了~
明天可以來玩一些細部的調整。